package com.liming.user.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.liming.cart.client.CartClient;
import com.liming.common.constant.SystemConstants;
import com.liming.common.pojo.dto.cart.AddItemToCartDTO;
import com.liming.common.pojo.dto.cart.ItemInCartDTO;
import com.liming.common.pojo.vo.cart.openfeign.FeignProductInCartVO;
import com.liming.common.pojo.vo.cart.web.ProductInCartVO;
import com.liming.common.pojo.vo.cart.web.UserCartVO;
import com.liming.common.pojo.vo.coupon.GoodCouponVO;
import com.liming.common.pojo.vo.coupon.openfeign.FeignMiniCouponVO;
import com.liming.common.pojo.vo.product.BaseProductVO;
import com.liming.common.pojo.vo.product.openfeign.FeignProductVO;
import com.liming.common.util.BeanUtils;
import com.liming.common.util.ThreadLocalUtils;
import com.liming.coupon.client.CouponUserClient;
import com.liming.product.client.ProductClient;
import com.liming.user.service.CartService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author liming
 * @date 2025/3/24
 */
@Slf4j
@Service
@AllArgsConstructor
public class CartServiceImpl implements CartService {

    private final CartClient cartClient;
    private final ProductClient productClient;
    private final CouponUserClient couponUserClient;

    @Override
    public List<ProductInCartVO> getProductInCart() {
        List<FeignProductInCartVO> feignResult = cartClient.getProductInCart();
        return BeanUtils.toBean(feignResult, ProductInCartVO.class);
    }

    @Override
    public Boolean addItemToCart(AddItemToCartDTO dto) {
        return cartClient.addItemToCart(dto);
    }

    @Override
    public UserCartVO userCartInfo(List<ItemInCartDTO> list) {
        long userId = Long.parseLong(ThreadLocalUtils.get(SystemConstants.ID));
        UserCartVO vo = new UserCartVO();
        List<Long> itemIds = list.stream().map(ItemInCartDTO::getProductId).toList();
        List<FeignProductVO> feignProductVOS = productClient.listByIds(itemIds);
        Map<Long, Integer> itemIdAndPriceMap = feignProductVOS.stream().collect(Collectors.toMap(FeignProductVO::getId, FeignProductVO::getPrice));
        // 购物车总体金额
        Integer totalPrice = list.stream().map(item -> {
            Long itemId = item.getProductId();
            Integer price = itemIdAndPriceMap.get(itemId);
            return price * item.getQuantity();
        }).reduce(Integer::sum).orElse(0);
        vo.setTotalPrice(totalPrice);
        // 使用该金额去查询优惠券 每个订单最多使用一个优惠券 查询优惠最大的一个优惠券
        // 查询用户所有的优惠券
        List<FeignMiniCouponVO> userCoupons = couponUserClient.userHaveCoupons(userId);
        if (CollUtil.isEmpty(userCoupons)) {
            return vo;
        }
        List<FeignMiniCouponVO> sortedUserCoupons = userCoupons.stream().sorted(Comparator.comparing(FeignMiniCouponVO::getDiscountAmount).reversed()).toList();
        GoodCouponVO goodCoupon = new GoodCouponVO();
        for (FeignMiniCouponVO sortedUserCoupon : sortedUserCoupons) {
            // 最低消费金额
            Integer minPurchaseAmount = sortedUserCoupon.getMinPurchaseAmount();
            if (totalPrice >= minPurchaseAmount) {
                // 优惠券名称
                vo.setCouponName(sortedUserCoupon.getName());
                // 优惠券折扣金额
                vo.setCouponDiscountAmount(sortedUserCoupon.getDiscountAmount());
                // 购物车优惠后价格
                vo.setAfterCouponTotalPrice(totalPrice - sortedUserCoupon.getDiscountAmount());
                break;
            }
            goodCoupon.setId(sortedUserCoupon.getId());
            goodCoupon.setDiscountAmount(sortedUserCoupon.getDiscountAmount());
            goodCoupon.setNeedConsumeAmount(minPurchaseAmount - totalPrice);
        }
        vo.setGoodCouponVO(goodCoupon);
        // 购物车中商品信息 List<ProductInCartVO> productInCartVOList;
        Map<Long, FeignProductVO> idAndProductVOMap = feignProductVOS.stream().collect(Collectors.toMap(BaseProductVO::getId, Function.identity()));
        List<ProductInCartVO> productInCartVOS = BeanUtils.toBean(list, ProductInCartVO.class);
        for (ProductInCartVO productInCartVO : productInCartVOS) {
            Long productId = productInCartVO.getProductId();
            FeignProductVO feignProductVO = idAndProductVOMap.get(productId);
            Integer price = feignProductVO.getPrice();
            productInCartVO.setProductName(feignProductVO.getName());
            productInCartVO.setPrice(price);
            productInCartVO.setMainImageUrl(feignProductVO.getMainImageUrl());
            // 优惠券后价格
            // 商品占比 = 商品金额 / 购物车金额
            double rate = price / totalPrice.doubleValue();
            // 优惠券后价格 = 商品占比 * 购物车优惠后价格
            // 如果没有选中优惠券呢？
            if (ObjectUtil.isNull(vo.getAfterCouponTotalPrice()) || ObjectUtil.isNull(vo.getCouponDiscountAmount())) {
                productInCartVO.setAfterCouponPrice(BigDecimal.valueOf(totalPrice.doubleValue() / 100.0).setScale(2, RoundingMode.HALF_UP).doubleValue());
            } else {
                productInCartVO.setAfterCouponPrice(BigDecimal.valueOf(rate * vo.getAfterCouponTotalPrice().doubleValue() / 100.0).setScale(2, RoundingMode.HALF_UP).doubleValue());
            }
        }
        vo.setProductInCartVOList(productInCartVOS);
        return vo;
    }

    @Override
    public Boolean reduceItemById(Long id) {
        return cartClient.reduceItemById(id);
    }

    @Override
    public Boolean addItemById(Long id) {
        return cartClient.addItemById(id);
    }

    @Override
    public Boolean deleteItemsByIds(List<Long> ids) {
        return cartClient.removeItemsByIds(ids);
    }
}
